#include "GLTexture.h"

GLTexture::GLTexture(GLuint name, GLenum target, GLint internalFormat, GLsizei width, GLsizei height, bool immutable)
	: name(name), target(target), internalFormat(internalFormat), width(width), height(height), immutable(immutable),
	minFilter(GL_NEAREST_MIPMAP_LINEAR), magFilter(GL_LINEAR), wrap(GL_REPEAT)
{

}

GLTexture::~GLTexture()
{
	glDeleteTextures(1, &name);
}

GLTexture* GLTexture::newMutable(GLenum target, GLint internalFormat, GLsizei width, GLsizei height/* =1 */, GLenum format/* =GL_RGBA */, GLenum type/* =GL_FLOAT */, void *data/* =NULL */)
{
	GLuint name;
	glGenTextures(1, &name);
	GLTexture* ret = new GLTexture(name, target, internalFormat, width, height, false);
	glBindTexture(target, name);
	if (target==GL_TEXTURE_1D)
	{
		glTexImage1D(target,0,internalFormat,width,0,format,type,data);
	}
	else if(target == GL_TEXTURE_2D || target == GL_TEXTURE_1D_ARRAY)
	{
		glTexImage2D(target,0,internalFormat,width,height,0,format,type,data);
	}
	return ret;
}

GLTexture* GLTexture::newImmutable(GLenum target, GLint internalFormat, GLsizei width, GLsizei height/* =1 */, GLenum format/* =GL_RGBA */, GLenum type/* =GL_FLOAT */, void *data/* =NULL */)
{
	GLuint name;
	glGenTextures(1, &name);
	GLTexture* ret = new GLTexture(name, target, internalFormat, width, height, false);
	glBindTexture(target, name);
	if (target==GL_TEXTURE_1D)
	{
		glTexStorage1D(target,1,internalFormat,width);
		if (data!=NULL)
		{
			glTexSubImage1D(target,0,0,width,format,type,data);
		}
	}
	else if(target == GL_TEXTURE_2D || target == GL_TEXTURE_1D_ARRAY)
	{
		glTexStorage2D(target,1,internalFormat,width,height);
		if (data != NULL)
		{
			glTexSubImage2D(target,0,0,0,width,height,format,type,data);
		}
	}
	return ret;
}

void GLTexture::setFilters(GLint minFilter, GLint magFilter)
{
	this->minFilter = minFilter;
	this->magFilter = magFilter;
	glBindTexture(target, name);
	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter);
	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
}

void GLTexture::setWrap(GLint wrap)
{
	this->wrap=wrap;
	glBindTexture(target,name);
	glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
	glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
}

void GLTexture::setContents(GLenum format, GLenum type, void* data)
{
	glBindTexture(target,name);
	if (target==GL_TEXTURE_1D)
	{
		glTexSubImage1D(target,0,0,width,format,type,data);
	}
	else if(target == GL_TEXTURE_2D || target == GL_TEXTURE_1D_ARRAY)
	{
		glTexSubImage2D(target,0,0,0,width,height,format,type,data);
	}
}